package org.c41.graphics.render;

import org.c41.util.Check;
import org.c41.util.time.TimeUtil;

public class FPSTimer {

	private static final int NO_DELAYS_PER_YIELD = 16;
	
	private long last_time;
	private long current_time;
	private long time_diff=0L;
	
	private int no_delay_count=0;
	private long fps_count=0L;
	private long fps_count_time=0L;
	
	private final int fps;
	
	public FPSTimer(int fps){
		Check.greater(fps, 0);
		this.current_time=TimeUtil.nanoTime()/1000000L;
		this.last_time=this.current_time;
		this.fps=fps;
	}
	
	public void update(){
		this.last_time=this.current_time;
		this.current_time=TimeUtil.nanoTime()/1000000L;
		this.time_diff=this.current_time-this.last_time;
		this.fps_count+=1L;
		this.fps_count_time+=this.time_diff;
	}
	
	public void pause(){
		long sleepTime = getPausingTime();
		if(sleepTime>0L){
			try {
				Thread.sleep(sleepTime);
			} catch (InterruptedException e) {
			}
		}
		else if(++this.no_delay_count>=NO_DELAYS_PER_YIELD){
			Thread.yield();
			this.no_delay_count=0;
		}
	}
	
	public long getPausingTime(){
		long sleepTime = 1000L*fps_count/fps-fps_count_time;
		return sleepTime<0 ? 0L : sleepTime;
	}
	
	public long getSpacingTime(){
		return this.time_diff;
	}
	
	public int getFps(){
		return this.fps;
	}
	
}